﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace TagCloud {
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:Cloud runat=server></{0}:Cloud>")]
    public class Cloud : WebControl {
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("Tags")]
        [Localizable(true)]
        public string Text {
            get {
                String s = (String)ViewState["Text"];
                return ((s == null) ? String.Empty : s);
            }

            set {
                ViewState["Text"] = value;
            }
        }
        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("TagCloud")]
        [Localizable(false)]
        public string JavascriptName {
            get {
                String s = (String)ViewState["JavascriptName"];
                return ((s == null) ? "_TagCloud" : s);
            }

            set {
                ViewState["JavascriptName"] = value;
            }
        }
        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue(" [x] ")]
        [Localizable(false)]
        public string Seperator {
            get {
                String s = (String)ViewState["Seperator"];
                return ((s == null) ? " [x] " : s);
            }

            set {
                ViewState["Seperator"] = value;
            }
        }
        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("null")]
        [Localizable(false)]
        public string OnClientClick {
            get {
                String s = (String)ViewState["OnClientClick"];
                return ((s == null) ? "null" : s);
            }

            set {
                ViewState["OnClientClick"] = value;
            }
        }
        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("true")]
        [Localizable(false)]
        public bool AllowDeletingOfTags {
            get {
                object a = ViewState["AllowDeletingOfTags"];
                if(a != null) return (bool)a;
                return true;
            }

            set {
                ViewState["AllowDeletingOfTags"] = value;
            }
        }

        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("true")]
        [Localizable(false)]
        public bool AllowAddingOfNewTags {
            get {
                object a = ViewState["AllowAddingOfNewTags"];
                if(a != null) return (bool)a;
                return true;
            }

            set {
                ViewState["AllowAddingOfNewTags"] = value;
            }
        }

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public TagCloud.TagList TagList {
            get {
                TagCloud.TagList l = (TagCloud.TagList)ViewState["TagList"];
                return l;
            }

            set {
                ViewState["TagList"] = value;
            }
        }

        string[] FontSizes = new string[] { "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large" };
        string SpacerMarkup = "<br />";  //what to place inbetween each tag in the cloud

        protected override void RenderContents(HtmlTextWriter output) {
            System.Text.StringBuilder sb = RenderTagCloud();
            output.Write(Text);
            output.Write(sb.ToString());
        }
        protected override void OnInit(EventArgs e) {
            base.OnInit(e);
            this.Page.ClientScript.RegisterClientScriptResource(resType, "TagCloud.Tags.Tags.js");

        }
        public TagCloud.TagList ActiveTags {
            get {
                TagCloud.TagList list = new TagCloud.TagList();
                return list;
            }
        }
        Type resType = typeof(TagCloud.Cloud);
        protected System.Text.StringBuilder RenderTagCloud() {
            System.Text.StringBuilder sb = new StringBuilder();
            System.Text.StringBuilder jsSB = new StringBuilder();
            SetMaxMin();
            if(this.TagList != null) {

                //sb.Append("<script language=\"javascript\" type=\"text/javascript\" src=\"Tags/Tags.js\"></script>\n");
                jsSB.Append("<div id='TagsContainer'></div><script language=\"javascript\" >\n");
                jsSB.Append(string.Format("\nvar cloudControl=document.getElementById('TagsContainer');\nvar {0} = new Tags(cloudControl, '{0}');\n{0}.AllowAdd={1};\n{0}.AllowDelete={2};\n{0}.Seperator='{3}';\n\n", this.JavascriptName, this.AllowAddingOfNewTags.ToString().ToLower(), this.AllowDeletingOfTags.ToString().ToLower(), this.Seperator, this.ClientID));
                if(this.OnClientClick == null || this.OnClientClick == "" || this.OnClientClick == "null") {
                    jsSB.Append(string.Format("{0}.DefaultOnClientClick='{1}';\n", this.JavascriptName, this.OnClientClick));
                }
                int x = 0;
                foreach(TagCloud.Tag tag in this.TagList) {
                    decimal num = Convert.ToDecimal(tag.TagCount);
                    int Scale = (int)Math.Truncate((num - Min) / scaleUnitLength);
                    //sb.Append(string.Format("<a href=\"\" style=\"font-size:{3}\">{0}-{1}</a> <span class=\"tagx\" onclick=\"{4}.Remove('{0}')\">[x]</span>{2}\n", tag.TagText, tag.TagCount, SpacerMarkup, FontSizes[Scale], this.JavascriptName));
                    if(tag.OnClientClick == null || tag.OnClientClick == "" || tag.OnClientClick == "null") tag.OnClientClick = this.OnClientClick;
                    jsSB.Append(string.Format("var t{6} = {0}.Add(new Tag('{1}', {2}, '{3}', {4}, \"{5}\"));\n", this.JavascriptName, tag.TagText, tag.TagCount, FontSizes[Scale], tag.Enabled.ToString().ToLower(), tag.OnClientClick, x));
                    x++;
                }
                jsSB.Append("</script>");
                sb.Append(jsSB.ToString());
                if(AllowAddingOfNewTags) {
                    sb.Append("<br /><span style='color:#c0c0c0;font-size:small;cursor:pointer' onclick=\"" + this.JavascriptName + ".ShowAddInput();\">Add New Tag</span>");
                }
            }
            return sb;
        }


        decimal scaleUnitLength;
        private long Max = 0;
        private long Min = 99999999;  //some arbritrary large number
        protected void SetMaxMin() {
            if(this.TagList != null) {
                foreach(TagCloud.Tag tag in this.TagList) {
                    Max = Math.Max(tag.TagCount, Max);
                    Min = Math.Min(tag.TagCount, Min);
                }
            }
            scaleUnitLength = (Max - Min + 1) / Convert.ToDecimal(FontSizes.Length);
        }


    }
}
